package com.afdor.rws.event.driven.config;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.annotation.extension.SPI;
import com.afdor.rws.event.driven.commons.Constants;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 消费者相关配置<br/>
 * Extension : prototype
 *
 * @author 悭梵
 * @date Created in 2018-11-21 15:45
 */
@Getter
@SPI(Constants.DEFAULT_COMPONENT_CONFIG_EXTENSION_NAME)
@Extension(value = Constants.DEFAULT_COMPONENT_CONFIG_EXTENSION_NAME, scope = Extension.Scope.PROTOTYPE, interfaceClass = EventConsumerConfig.class)
public class EventConsumerConfig<BC extends EventConfig> extends BaseEventConfig<BC> implements Serializable, Cloneable {

    /**
     * 事件源名称
     */
    @Setter
    @NonNull
    private String eventSourceName;
    /**
     * 消费者名称。默认default
     */
    @Setter
    private String consumerName = "default";
    /**
     * 消费者事件重试策略扩展点名称。默认default，由EventRetryStrategy.SPI("default")负责激活默认值。
     */
    @Setter
    private String eventRetryStrategyName;
    /**
     * 消费者扩展点名称，必填。各种实现方式，存在默认值不一样情况
     */
    @Setter
    @NonNull
    private String eventConsumerStrategyName;
    /**
     * 事件序列化扩展点名称，必填。各种实现方式，存在默认值不一样情况
     */
    @Setter
    @NonNull
    private String serializationStrategyName;
    /**
     * 处理空闲间隔
     */
    @Setter
    private int eventHandlerPeriod = 200;
    /**
     * 构造器初始化入参，为空，则调用无参构造函数
     */
    private Object[] constructorArgs;
    /**
     * 过滤tag标签
     */
    @Setter
    private Map<String, String> filterTagMap;
    /**
     * 批量处理事件数据
     */
    @Setter
    private int batchSize = -1;
    /**
     * 事件最大重试次数
     */
    @Setter
    private int maxRetryCount = 6;

    public EventConsumerConfig() {

    }

    public EventConsumerConfig(@NonNull final BC eventConfig) {
        setEventConfig(eventConfig);
    }

    public <T extends EventConsumerConfig> T addTag(@NonNull String tagLabel, String value) {
        if (this.filterTagMap == null) {
            this.filterTagMap = new HashMap<>(8);
        }
        this.filterTagMap.put(tagLabel, value);
        return (T) this;
    }

    public void setConstructorArgs(Object... args) {
        this.constructorArgs = args;
    }
}
